home *** CD-ROM | disk | FTP | other *** search
- {
- Ripples generator, by Maple Leaf, Nov 1996
- v2.0
- ----------------------------------------------------------------------------
- ASM RULES!!!! yup, yup. the others suck. assembler forever !
- ----------------------------------------------------------------------------
- Do whatever you want with this crappy code, but if you use parts of it in
- your production(s), please send some greets to Maple Leaf (Gruian Radu).
- Thanx.
- }
-
- uses alloc, files, bitmap;
-
- var vScr, sqrTab : word;
- Img : pointer;
- Pal : array[byte] of record r,g,b:byte end;
-
- Wave : array [0..199] of word; { 200 words are quite enough ... }
-
- SinTab : array [byte] of longint;
-
- procedure InitVideo;near;assembler;
- asm
- mov ax,13h
- int 10h { init video mode }
- mov dx,3c8h
- mov al,0
- out dx,al
- inc dx
- mov cx,768
- mov si,offset pal
- rep outsb { set palette }
- end;
-
- procedure vWait;near;assembler;
- asm
- mov dx,3DAh
- @1: in al,dx
- test al,8
- jne @1
- @2: in al,dx
- test al,8
- je @2
- end;
-
- procedure ShowVScreen;near;assembler;
- asm
- push ds
- push es
- mov cx,16000
- mov ax,0A000h
- mov es,ax
- mov di,0
- mov si,di
- mov ds,VScr
- cld
- db 66h; rep movsw
- pop es
- pop ds
- end;
-
- procedure freeAll;
- begin
- free(img);
- hfree(vScr);
- hfree(sqrTab);
- end;
-
- procedure InitData;
- var k:word;
- begin
- vScr:=halloc(64000);
- sqrTab:=halloc(161*101*2); { [0..160,0..100] of word }
- Img:=LoadPCX(paramstr(1),@pal);
- if (Img=nil) or (vScr=0) or (sqrTab=0) then begin
- freeAll;
- asm mov ax,3; int 10h end;
- writeln('Not enough memory');
- halt
- end;
- for k:=0 to 255 do SinTab[k]:=trunc(256*sin(k/255*2*pi));
- end;
-
- procedure PreCalc; { this shit will take some time... }
- var x,y,k:word; { it could be stored once and loaded from disk every time }
- ff:file;
- begin
- for x:=0 to 160 do
- for y:=0 to 100 do begin
- k:=trunc( sqrt( sqr(x) + sqr(y) ) );
- memw[sqrTab:(y*161+x)*2]:=k;
- end;
- (*
- openforoutput(ff,'dist_tab.dat','');
- blockwrite(ff,mem[sqrTab:0],161*101); { just in case you'll ever need it... }
- closefile(ff,'');
- *)
- end;
-
- var ang:word;
-
-
- {
- Rutina asta ar trebui setata sa "introduca" sinusul în unda, sa valureasca
- putin si apoi sa-l "scoata" afara cu scaderea treptata a amplitudinii (în
- felul asta de obtine un efect de "drop"-valuri de picatura de apa).
- (usor de facut, oricum...)
- ---------------------------------------------------------------------------
- "forma de unda" e tinuta în Wave[] (200 de intrari). Intrarea 0 corespunde
- altitudinii "centrului" imaginii generate (centrul cercurilor concentrice).
- Intrarea 199 - celor mai exterioare puncte din figura (extremitatile-colturi,
- margini(?)).
- Sinusul se deplaseaza în forma de unda de la 0 înspre 199, pentru a da
- impresia de "deplasare" a frontului de unda (a "valurilor").
- }
- procedure UpdateWave;
- const Amplitude : word = 10; { in pixels } { can vary ! }
- Frequency : word = 15; { ripples/(160 pixels) } { can vary ! }
- var k:word;
- begin
- inc(ang,1);
- for k:=0 to 189{199} do {189 is the exact value}
- Wave[k]:=Amplitude*sinTab[byte(Frequency*(k-ang))] div 256;
- end;
-
- procedure DrawRipples;near;external; {$L rip_asm} { the main shit, hehehe }
-
- procedure DoIt;
- begin
- Precalc;
- repeat
- UpdateWave;
- DrawRipples;
- vWait;
- ShowVScreen;
- until port[$60]=1;
- end;
-
- begin
- if paramcount=0 then begin
- writeln('RIPPLES FileName.PCX');
- halt
- end;
- InitData;
- InitVideo;
- DoIt;
- asm mov ax,3; int 10h end;
- freeAll;
- end.
-